import { fromCallback, checkError } from '../../universalify'
import path from '../../node/path'
import fs from '../fs'
import mkdir from '../mkdirs'
import errorCode from '../../node/error-code'

function createFile (file, callback) {
    function makeFile () {
        fs.writeFile(file, '', err => {
            if (checkError(err)) return callback(err)
            callback()
        })
    }

    fs.stat(file, (err, stats) => { // eslint-disable-line handle-callback-err
        if (!err && stats.isFile()) return callback()
        const dir = path.dirname(file)
        fs.stat(dir, (err, stats) => {
            if (checkError(err)) {
                // if the directory doesn't exist, make it
                if (err.message === errorCode.errormessage.ENOENT) {
                    return mkdir.mkdirs(dir, err => {
                        if (checkError(err)) return callback(err)
                        makeFile()
                    })
                }
                return callback(err)
            }

            if (stats.isDirectory()) makeFile()
            else {
                // parent is not a directory
                // This is just to cause an internal ENOTDIR error to be thrown
                fs.readdir(dir, err => {
                    if (checkError(err)) return callback(err)
                })
            }
        })
    })
}

function createFileSync (file) {
    let stats
    try {
        stats = fs.statSync(file)
    } catch (err) {}
    if (stats && stats.isFile()) return;

    const dir = path.dirname(file)
    try {
        if (!fs.statSync(dir).isDirectory()) {
            // parent is not a directory
            // This is just to cause an internal ENOTDIR error to be thrown
            fs.readdirSync(dir)
        }
    } catch (err) {
        // If the stat call above failed because the directory doesn't exist, create it
        if (err && err.message === errorCode.errormessage.ENOENT) mkdir.mkdirsSync(dir)
        else throw err
    }

    fs.writeFileSync(file, '')
}

export default {
    createFile: fromCallback(createFile),
    createFileSync
}
